package JUnit;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.junit.Test;

import Model.Market;
import Model.TradeGood;

/**
 * This class tests Market's buy item on 17 different
 * market types. Though not all combinations are represented
 * all subtypes (governments, tech levels, and planet states)
 * are included.
 * @author Whitney
 * @version 1.0
 */
public class WhitneyBuyItemTest {

	/**
	 * Basic Variables
	 */
	private int level, gov, state;
	/**
	 * Random Generator
	 */
	Random gen = new Random();
	/**
	 * creates an array of 17 unique markets
	 */
	Market[] marketArray = new Market[17];
	
	/**
	 * Runs tests on BuyItem
	 * @author Whitney
	 */
	@Test
	public void test() throws Exception{
		HashMap<String, TradeGood> marketMap = new HashMap<String, TradeGood>();
		for(int i= 0; i<marketArray.length; i++){
			//Picks random levels and states for markets after all have
			//been initially represented.
			if(i >=7){
				state = gen.nextInt(5) + 1;
			}
			else{
				state = i;
			}
			if(i >= 9){
				level = gen.nextInt(7) + 1;
			}
			else{
				level = i;
			}
			gov = i;
			marketArray[i] = new Market(level, gov, state);
		}
		//Basic Tests, making sure each market develops the appropriate stuff
		for(int i = 0; i < 17; i++){
		Market tester = marketArray[i];
		tester.setMarketMap(marketMap);
		String itemKey = "";
		int currCargo = 1;
		int maxCargo = 1;
		int playerMoney = 1;
		int quantity = 1;
		HashMap<String, TradeGood> shipCargo = new HashMap<String, TradeGood>();

		Map<String, Object> result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);

		//test basic buy item requirements
		assertNotNull(result);
		assertEquals(3, result.size());
		assertEquals(new Integer(1), result.get("Player Money"));
		assertEquals(new Integer(1), result.get("Current Cargo"));
		assertTrue(result.containsKey("Cargo"));
		}
		//Buying Tests. Created dummy items to test.
		//Each Market is tested
		
		Map<String, Object> result = new HashMap<String, Object>();
		for(int j = 0; j <17; j++){
		HashMap<String, TradeGood> shipCargo = new HashMap<String, TradeGood>();
		Market tester = marketArray[j];
		
		//All items are priced at 30
		//2 of every item is available
		marketMap.put("Water", new TradeGood("Water", 0, 1, 30, 2));//water
		marketMap.put("Furs", new TradeGood("Furs", 1, 1, 30, 2));//Furs
		marketMap.put("Food", new TradeGood("Food", 2, 1, 30, 2));//Food
		marketMap.put("Games", new TradeGood("Games", 9, 1, 30, 2));//Games
		marketMap.put("Medicine", new TradeGood("Medicine", 4, 1, 30, 2));//Medicine
		marketMap.put("Narcotics", new TradeGood("Narcotics", 5, 1, 30, 2));//Narcotics
		marketMap.put("Firearms", new TradeGood("Firearms", 6, 1, 30, 2));//Firearms
		marketMap.put("Robots", new TradeGood("Robots", 7, 1, 30, 2));//Robot
		//marketMap.put("Machines", new TradeGood("Machines", 8, 1, 30, 2));//Machines
		//MACHINES marked as null to test null
		marketMap.put("Ore", new TradeGood("Ore", 3, 1, 30, 2));//Ore (Buy price -100 because they sell cheap ore)
		tester.setMarketMap(marketMap);
		//test if there is no space in player ship, nothing is changed
		String itemKey = "Water";
		int currCargo = 2;
		int maxCargo = 2;
		int playerMoney = 100;
		int quantity = 2;
		
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);

		//Attempted to purchase all water. If call went through, water should equal null
		//And player money and current cargo shouldn't change
		assertTrue(tester.getMarketMap().get("Water") != null);
		assertEquals(100, result.get("Player Money"));
		assertEquals(2, result.get("Current Cargo"));
		
		//test if there is money is less than buy item, nothing is changed
		itemKey = "Food";
		currCargo = 1;
		maxCargo = 9;
		playerMoney = 20;
		quantity = 2;
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);
		
		//Attempted to purchase all food. If call went through, water should equal null
		//And player money shouldn't change
		assertTrue(tester.getMarketMap().get("Food") != null);
		assertEquals(20, result.get("Player Money"));
		assertEquals(1, result.get("Current Cargo"));
		
		//test that if too many items want to be bought, nothing is changed
		itemKey = "Furs";
		currCargo = 1;
		maxCargo = 9;
		playerMoney = 100;
		quantity = 5;
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);
		
		assertTrue(tester.getMarketMap().get("Furs") != null);
		assertEquals(100, result.get("Player Money"));
		assertEquals(1, result.get("Current Cargo"));
		
		//test that cannot buy null item
		itemKey = "Machines";
		currCargo = 1;
		maxCargo = 9;
		playerMoney = 100;
		quantity = 1;
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);
		
		//Machines should still equal null, and player money shouldn't change
		assertTrue(tester.getMarketMap().get("Machines") == null);
		assertEquals(100, result.get("Player Money"));
		assertEquals(1, result.get("Current Cargo"));
		
		//test that can buy if there is enough money, item, and space
		//Purchased robots because everybody loves robots
		//Check that if all items are purchased, Item goes to null
		itemKey = "Robots";
		currCargo = 1;
		maxCargo = 9;
		playerMoney = 100;
		quantity = 2;
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);
		
		//Robots should now equal null, player money should be reduced by 60, current cargo
		//should now equal 3
		assertTrue(tester.getMarketMap().get("Robots") == null);
		assertEquals(40, result.get("Player Money"));
		assertEquals(3, result.get("Current Cargo"));
		
		//test that can buy if there is enough money, item, and space
		//Check that if not all items are purchased, Item does not go to null
		itemKey = "Ore";
		currCargo = 1;
		maxCargo = 9;
		playerMoney = 100;
		quantity = 1;
		result = tester.buyItem(itemKey, currCargo, maxCargo, playerMoney, quantity, shipCargo);
				
		//Robots should not equal null, player money should be reduced by 30, current cargo
		//should now equal 2
		assertTrue(tester.getMarketMap().get("Ore") != null);
		assertEquals(70, result.get("Player Money"));
		assertEquals(2, result.get("Current Cargo"));
		}
	}

}
